package com.med.service.impl;

import com.med.dto.RespondDTO;
import com.med.entity.DoctorDO;
import com.med.entity.UserDO;
import com.med.mapper.UserFrontMapper;
import com.med.service.IUserFrontService;
import com.med.util.SendCodeUtil;
import com.med.util.ValidateCodeUtil;
import com.med.vo.UserVO;
import com.ruoyi.common.core.utils.JwtUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.security.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @BelongsProject: internet-based-healthcare
 * @BelongsPackage: com.med.service.impl
 * @Author: 小吴
 * @CreateTime: 2025-08-17 16:58
 * @Description: TODO
 * @Version: 1.0
 */
@Service
public class UserFrontServiceImpl implements IUserFrontService {

    @Autowired
    private UserFrontMapper userFrontMapper;

    @Autowired
    private SendCodeUtil sendCodeUtil; //短信验证码

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    /**
     * @Description: 用户端登录
     * @Param:
     * @return:
     */
    @Override
    public RespondDTO login(UserVO userVO) {
        //获取redis中的验证码，CodeKey是存redis的标识
        String vCode = redisTemplate.opsForValue().get(userVO.getCodeKey());
        //获取用户输入的验证码
        String code = userVO.getCode();

        //获取登录的用户对象
        UserDO login = userFrontMapper.login(userVO);

        //用户输入的密码
        String password = userVO.getPassword();
        //根据用户名查询到的密码
        String userPassword = login.getUserPassword();

        //判断输入的密码是否与数据库密码一致
        boolean matchesPassword = SecurityUtils.matchesPassword(password, userPassword);

        if (!matchesPassword) {
            return new RespondDTO(2, "密码错误,请输入正确的密码", null);
        }

        //判断验证码是否正确，忽略大小写
        if (!vCode.equalsIgnoreCase(code)) {
            return new RespondDTO(3, "验证码错误", null);
        }

        if (login != null) {
            //生成token
            String token = createToken(login);
            return RespondDTO.success(token);
        }
        return null;
    }

    /**
    * @Description: 将对应的用户数据生成token
    * @Param:
    * @return:
    */
    private String createToken(UserDO commentClass) {
        HashMap<String, Object> hashMap = new HashMap<>();

        hashMap.put("userName", commentClass.getUserName());
        hashMap.put("userId", commentClass.getUserId());
        hashMap.put("userAccount", commentClass.getUserAccount());
        hashMap.put("userPhoneNumber", commentClass.getUserPhoneNumber());
        hashMap.put("userAvatar", commentClass.getUserAvatar());
        hashMap.put("userPassword", commentClass.getUserPassword());
        //生成token
        String token = JwtUtils.createToken(hashMap);
        //设置token存储到redis，并且存储时间为30分钟，过期自动删除
        redisTemplate.opsForValue().set("tokenTestHealth", token, 30, TimeUnit.MINUTES);
        return token;
    }

    /**
     * @Description: 检测账号名是否重复
     * @Param:
     * @return:
     */
    @Override
    public RespondDTO judgeAccount(UserVO userVO) {
        UserDO judgedAccount = userFrontMapper.judgeAccount(userVO);
        if (judgedAccount != null) {
            return RespondDTO.success(judgedAccount);
        }
        return null;
    }

    /**
     * @Description: 判断数据库中的手机号
     * @Param:
     * @return:
     */
    @Override
    public RespondDTO isExitPhone(UserVO userVO) {
        UserDO exitPhone = userFrontMapper.isExitPhone(userVO);
        if (exitPhone != null) {
            return RespondDTO.success(exitPhone);
        }
        return null;
    }

    /**
     * @Description: 短信发送验证码
     * @Param:
     * @return:
     */
    @Override
    public RespondDTO sendCode(UserVO userVO) {
        //生成验证码
        String code = ValidateCodeUtil.generateCode();
        System.err.println(code);
        String phone = userVO.getPhone(); //获取到phone
        System.out.println(phone);

        sendCodeUtil.sendVerificationCode(phone, code);
        //验证码存redis
        redisTemplate.opsForValue().set("userFrontCode", code, 5, TimeUnit.MINUTES);

        return RespondDTO.success();
    }

    /**
     * @Description: 用户注册
     * @Param:
     * @return:
     */
    @Override
    public RespondDTO register(UserVO userVO) {
        String password = userVO.getPassword();
        String surePassword = userVO.getSurePassword();
        //两次输入的密码是否相等
        if (!password.equals(surePassword)) {
            return new RespondDTO(-1, "两次密码不同", null);
        }
        //密码加密
        String encryptPassword = SecurityUtils.encryptPassword(password);
        userVO.setBCryptPassword(encryptPassword);

        String codeRedis = redisTemplate.opsForValue().get("userFrontCode");
        String code = userVO.getCode();
        //判断验证码是否过期
        if (codeRedis.isEmpty()) {
            return new RespondDTO(-2, "验证码过期，请重新获取", null);
        }
        //验证码是否正确
        if (!code.equals(codeRedis)) {
            return new RespondDTO(-3, "验证码错误，请重新获取", null);
        }

        Integer register = userFrontMapper.register(userVO);
        if (register != null) {
            return RespondDTO.success(register);
        }
        return null;
    }

    /**
     * @Description: 发送验证码给手机号---用户登录
     * @Param:
     * @return:
     */
    @Override
    public RespondDTO getCodeTelLogin(UserVO userVO) {
        //获取到phone
        String phoneLogin = userVO.getPhoneLogin();

        //生成验证码
        String code = ValidateCodeUtil.generateCode();

        //发送给手机
        sendCodeUtil.sendVerificationCode(phoneLogin, code);

        //验证码存redis
        redisTemplate.opsForValue().set("userLoginCode", code, 5, TimeUnit.MINUTES);

        return RespondDTO.success();
    }

    /**
     * @Description: 用户登录--判断电话号码是否在表中
     * @Param:
     * @return:
     */
    @Override
    public RespondDTO telIsExit(UserVO userVO) {
        String phoneLogin = userVO.getPhoneLogin();

        // 1. 空值校验
        if (StringUtils.isBlank(phoneLogin)) {
            return RespondDTO.fail("手机号不能为空");
        }

        // 2. 正则表达式校验
        String phoneRegex = "^1[3-9]\\d{9}$"; // 严格匹配中国大陆手机号
        if (!phoneLogin.matches(phoneRegex)) {
            return RespondDTO.fail("手机号格式不正确");
        }

        // 3. 手机号码长度校验
        if (phoneLogin.length() != 11) {
            return RespondDTO.fail("手机号码长度不正确");
        }

        /*UserDO telIsExit = userFrontMapper.telIsExit(userVO);

        if (telIsExit != null) {
            return RespondDTO.success(telIsExit);

        }
        return new RespondDTO(-1, "该电话号码不存在，请重新输入", null);*/
        return RespondDTO.success();

    }

    /**
     * @Description: 验证码登录
     * @Param:
     * @return:
     */
    @Override
    public RespondDTO telLogin(UserVO userVO) {
        //用户输入的验证码
        String codeLogin = userVO.getCodeLogin();
        //redis中储存的验证码
        String code = redisTemplate.opsForValue().get("userLoginCode");
        if (code.isEmpty()) {
            return new RespondDTO(-1, "验证码过期，请重新获取", null);
        }
        if (!codeLogin.equalsIgnoreCase(code)) {
            return new RespondDTO(-2, "验证码输入错误", null);
        }
        UserDO telLogin = userFrontMapper.telLogin(userVO);
        if (telLogin != null) {
            //生成token
            String token = createToken(telLogin);
            return RespondDTO.success(token);
        }
        return null;
    }

    /**
    * @Description: 推荐医生
    * @Param:
    * @return:
    */
    @Override
    public RespondDTO commendDoctor() {
        List<DoctorDO> commendDoctor = userFrontMapper.commendDoctor();
        if (commendDoctor != null) {
            return RespondDTO.success(commendDoctor);
        }
        return null;
    }


}
